from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework.permissions import IsAuthenticated
from rest_framework_simplejwt.authentication import JWTAuthentication
from system.models import Notice, UserNotice, User
from system.SysUtils.permission import permission_required, data_permission_required
from .notices_serializers import NoticeCreateSerializer, NoticePageSerializer, NoticeDetailSerializer, NoticeFormSerializer, NoticeUpdateSerializer, NoticeMyPageSerializer
import jwt
from django.conf import settings
from django.db.models import Q, F, Case, When, Value, IntegerField
from django.utils import timezone
from django.shortcuts import get_object_or_404


class NoticePageView(APIView):
    """通知公告分页列表视图"""
    authentication_classes = [JWTAuthentication]
    permission_classes = [IsAuthenticated]
    
    @permission_required(["sys:notice:query"])
    def get(self, request, *args, **kwargs):
        """
        获取通知公告分页列表
        
        查询参数:
        - title: 通知标题（可选）
        - publishStatus: 发布状态(0-未发布 1-已发布 -1-已撤回)（可选）
        - publishTime: 发布时间(起止)（可选）
        - pageNum: 页码（必需）
        - pageSize: 每页记录数（必需）
        """
        # 获取查询参数
        title = request.query_params.get('title', '')
        publish_status = request.query_params.get('publishStatus', '')
        publish_time = request.query_params.get('publishTime', '')
        page_num = request.query_params.get('pageNum', '1')
        page_size = request.query_params.get('pageSize', '10')
        
        # 转换页码和每页记录数为整数
        try:
            page_num = int(page_num)
            page_size = int(page_size)
            # 边界检查
            if page_num < 1:
                page_num = 1
            if page_size < 1:
                page_size = 10
        except ValueError:
            return Response({
                "code": "A0400",
                "msg": "页码或每页记录数格式不正确"
            }, status=400)
        
        # 检查数据权限
        data_permission = None
        token = request.headers.get("Authorization")
        if token and token.startswith("Bearer "):
            token_str = token[7:]  # 去掉"Bearer "前缀
            data_permission = data_permission_required(token_str, "select")
        
        # 构建通知查询条件
        notice_query = Q(is_deleted=0)
        
        # 添加数据权限过滤
        if isinstance(data_permission, list) and data_permission:
            # 如果返回的是用户ID列表，只查询这些创建者的通知
            notice_query &= Q(create_by__in=data_permission)
        
        # 添加标题过滤
        if title:
            notice_query &= Q(title__icontains=title)
        
        # 添加发布状态过滤
        if publish_status != '':
            try:
                publish_status = int(publish_status)
                notice_query &= Q(publish_status=publish_status)
            except ValueError:
                pass
        
        # 添加发布时间过滤
        if publish_time:
            time_parts = publish_time.split(',')
            if len(time_parts) == 2:
                start_time, end_time = time_parts
                if start_time:
                    try:
                        start_date = timezone.datetime.strptime(start_time, '%Y-%m-%d %H:%M:%S')
                        notice_query &= Q(publish_time__gte=start_date)
                    except ValueError:
                        pass
                if end_time:
                    try:
                        end_date = timezone.datetime.strptime(end_time, '%Y-%m-%d %H:%M:%S')
                        notice_query &= Q(publish_time__lte=end_date)
                    except ValueError:
                        pass
        
        # 获取所有符合条件的通知
        notices = Notice.objects.filter(notice_query).order_by('-create_time')
        
        # 获取通知总数
        total = notices.count()
        
        # 计算分页偏移
        offset = (page_num - 1) * page_size
        paginated_notices = notices[offset:offset + page_size]
        
        # 序列化通知数据
        notice_list = NoticePageSerializer(paginated_notices, many=True).data
        
        # 返回分页结果
        return Response({
            "code": "00000",
            "data": {
                "list": notice_list,
                "total": total
            },
            "msg": "一切ok"
        })


class NoticeView(APIView):
    """通知公告管理视图"""
    authentication_classes = [JWTAuthentication]
    permission_classes = [IsAuthenticated]
    
    @permission_required(["sys:notice:query"])
    def get(self, request, *args, **kwargs):
        """
        获取通知公告列表
        
        查询参数:
        - title: 通知标题（可选）
        - publishStatus: 发布状态(0-未发布 1-已发布 -1-已撤回)（可选）
        - publishTime: 发布时间(起止)（可选）
        - pageNum: 页码（可选）
        - pageSize: 每页记录数（可选）
        """
        # 获取notice_id参数，如果存在，则获取单个通知详情
        notice_id = kwargs.get('notice_id')
        if notice_id:
            try:
                notice = Notice.objects.get(id=notice_id, is_deleted=0)
            except Notice.DoesNotExist:
                return Response({
                    "code": "A0404",
                    "msg": "通知公告不存在或已被删除"
                }, status=404)
            
            # 检查数据权限
            token = request.headers.get("Authorization")
            if token and token.startswith("Bearer "):
                token_str = token[7:]  # 去掉"Bearer "前缀
                data_permission = data_permission_required(token_str, "select", notice.create_by)
                if data_permission is False:
                    return Response({
                        "code": "A0401",
                        "msg": "无权限查看此通知公告"
                    }, status=403)
            
            # 返回通知详情
            serializer = NoticeDetailSerializer(notice)
            return Response({
                "code": "00000",
                "data": serializer.data,
                "msg": "一切ok"
            })
        
        # 否则，获取通知列表
        # 获取查询参数
        title = request.query_params.get('title', '')
        publish_status = request.query_params.get('publishStatus', '')
        publish_time = request.query_params.get('publishTime', '')
        page_num = request.query_params.get('pageNum', '1')
        page_size = request.query_params.get('pageSize', '10')
        
        # 转换页码和每页记录数为整数
        try:
            page_num = int(page_num)
            page_size = int(page_size)
            # 边界检查
            if page_num < 1:
                page_num = 1
            if page_size < 1:
                page_size = 10
        except ValueError:
            return Response({
                "code": "A0400",
                "msg": "页码或每页记录数格式不正确"
            }, status=400)
        
        # 检查数据权限
        data_permission = None
        token = request.headers.get("Authorization")
        if token and token.startswith("Bearer "):
            token_str = token[7:]  # 去掉"Bearer "前缀
            data_permission = data_permission_required(token_str, "select")
        
        # 构建通知查询条件
        notice_query = Q(is_deleted=0)
        
        # 添加数据权限过滤
        if isinstance(data_permission, list) and data_permission:
            # 如果返回的是用户ID列表，只查询这些创建者的通知
            notice_query &= Q(create_by__in=data_permission)
        
        # 添加标题过滤
        if title:
            notice_query &= Q(title__icontains=title)
        
        # 添加发布状态过滤
        if publish_status != '':
            try:
                publish_status = int(publish_status)
                notice_query &= Q(publish_status=publish_status)
            except ValueError:
                pass
        
        # 添加发布时间过滤
        if publish_time:
            time_parts = publish_time.split(',')
            if len(time_parts) == 2:
                start_time, end_time = time_parts
                if start_time:
                    try:
                        start_date = timezone.datetime.strptime(start_time, '%Y-%m-%d %H:%M:%S')
                        notice_query &= Q(publish_time__gte=start_date)
                    except ValueError:
                        pass
                if end_time:
                    try:
                        end_date = timezone.datetime.strptime(end_time, '%Y-%m-%d %H:%M:%S')
                        notice_query &= Q(publish_time__lte=end_date)
                    except ValueError:
                        pass
        
        # 获取所有符合条件的通知
        notices = Notice.objects.filter(notice_query).order_by('-create_time')
        
        # 获取通知总数
        total = notices.count()
        
        # 计算分页偏移
        offset = (page_num - 1) * page_size
        paginated_notices = notices[offset:offset + page_size]
        
        # 序列化通知数据
        notice_list = NoticePageSerializer(paginated_notices, many=True).data
        
        # 返回分页结果
        return Response({
            "code": "00000",
            "data": {
                "list": notice_list,
                "total": total
            },
            "msg": "一切ok"
        })
    
    @permission_required(["sys:notice:add"])
    def post(self, request, *args, **kwargs):
        """
        创建通知公告
        
        请求体参数:
        {
          "title": "通知标题",
          "content": "通知内容",
          "type": 通知类型,
          "level": "通知等级",
          "targetType": 目标类型(1: 全体, 2: 指定),
          "targetUserIds": ["用户ID1", "用户ID2"]
        }
        """
        # 获取token
        token = request.headers.get("Authorization")
        
        # 获取用户ID
        user_id = None
        if token and token.startswith("Bearer "):
            token_str = token[7:]  # 去掉"Bearer "前缀
            try:
                decoded_token = jwt.decode(token_str, settings.SIMPLE_JWT.get('SIGNING_KEY', settings.SECRET_KEY), algorithms=["HS256"])
                user_id = decoded_token.get('user_id')
            except jwt.InvalidTokenError:
                pass
        
        # 创建序列化器并验证数据
        serializer = NoticeCreateSerializer(
            data=request.data,
            context={'user_id': user_id, 'token': token}
        )
        
        if serializer.is_valid():
            # 创建通知公告
            notice = serializer.save()
            
            # 返回成功响应
            return Response({
                "code": "00000",
                "data": NoticeDetailSerializer(notice).data,
                "msg": "通知公告创建成功"
            })
        else:
            # 返回错误响应
            return Response({
                "code": "A0400",
                "msg": serializer.errors
            }, status=400)
    
    @permission_required(["sys:notice:edit"])
    def put(self, request, notice_id=None, *args, **kwargs):
        """
        修改通知公告
        
        路径参数:
        - notice_id: 通知公告ID
        
        请求体参数:
        {
          "id": 通知ID,
          "title": "通知标题",
          "content": "通知内容",
          "type": 通知类型,
          "level": "通知等级",
          "targetType": 目标类型(1: 全体, 2: 指定),
          "targetUserIds": ["用户ID1", "用户ID2"]
        }
        """
        # 获取通知公告ID
        if not notice_id:
            return Response({
                "code": "A0400",
                "msg": "请指定要更新的通知公告ID"
            }, status=400)
        
        # 获取token
        token = request.headers.get("Authorization")
        user_id = None
        
        if token and token.startswith("Bearer "):
            token_str = token[7:]  # 去掉"Bearer "前缀
            try:
                decoded_token = jwt.decode(token_str, settings.SIMPLE_JWT.get('SIGNING_KEY', settings.SECRET_KEY), algorithms=["HS256"])
                user_id = decoded_token.get('user_id')
            except jwt.InvalidTokenError:
                return Response({
                    "code": "A0401",
                    "msg": "无效的访问令牌"
                }, status=401)
        
        # 获取通知公告
        try:
            notice = Notice.objects.get(id=notice_id, is_deleted=0)
        except Notice.DoesNotExist:
            return Response({
                "code": "A0404",
                "msg": "通知公告不存在或已被删除"
            }, status=404)
        
        # 检查数据权限
        if token and token.startswith("Bearer "):
            token_str = token[7:]  # 去掉"Bearer "前缀
            data_permission = data_permission_required(token_str, "update", notice.create_by)
            
            if not data_permission:
                return Response({
                    "code": "A0401",
                    "msg": "无权限修改此通知公告"
                }, status=403)
            
        # 创建序列化器并验证数据
        serializer = NoticeUpdateSerializer(
            instance=notice,
            data=request.data,
            context={'user_id': user_id, 'token': token}
        )
        
        if serializer.is_valid():
            # 更新通知公告
            updated_notice = serializer.save()
            
            # 返回成功响应
            return Response({
                "code": "00000",
                "data": NoticeDetailSerializer(updated_notice).data,
                "msg": "通知公告更新成功"
            })
        else:
            # 返回错误响应
            return Response({
                "code": "A0400",
                "msg": serializer.errors
            }, status=400)
    
    @permission_required(["sys:notice:delete"])
    def delete(self, request, notice_id=None, *args, **kwargs):
        """
        删除通知公告
        
        路径参数:
        - notice_id: 单个通知公告ID（用于单个删除）
        
        查询参数:
        - ids: 通知公告ID列表，多个以英文逗号(,)分割（用于批量删除）
        """
        # 获取token和用户ID
        token = request.headers.get("Authorization")
        user_id = None
        
        if token and token.startswith("Bearer "):
            token_str = token[7:]  # 去掉"Bearer "前缀
            try:
                decoded_token = jwt.decode(token_str, settings.SIMPLE_JWT.get('SIGNING_KEY', settings.SECRET_KEY), algorithms=["HS256"])
                user_id = decoded_token.get('user_id')
            except jwt.InvalidTokenError:
                return Response({
                    "code": "A0401",
                    "msg": "无效的访问令牌"
                }, status=401)
        
        # 获取需要删除的通知ID
        notice_ids = []
        
        # 检查是否为批量删除（通过查询参数ids）
        batch_ids = request.query_params.get('ids', '')
        if batch_ids:
            # 批量删除模式
            notice_ids = batch_ids.split(',')
        elif notice_id:
            # 单个删除模式
            notice_ids = [str(notice_id)]
        else:
            # 没有提供任何ID
            return Response({
                "code": "A0400",
                "msg": "请指定要删除的通知公告ID"
            }, status=400)
        
        # 检查所有通知权限并分类
        authorized_notices = []
        unauthorized_notice_ids = []
        nonexistent_notice_ids = []
        
        for nid in notice_ids:
            try:
                notice_id_int = int(nid.strip())
                
                # 检查通知是否存在
                try:
                    notice = Notice.objects.get(id=notice_id_int, is_deleted=0)
                    
                    # 检查数据权限
                    if token and token.startswith("Bearer "):
                        token_str = token[7:]  # 去掉"Bearer "前缀
                        data_permission = data_permission_required(token_str, "delete", notice.create_by)
                        
                        if data_permission:
                            authorized_notices.append(notice)
                        else:
                            unauthorized_notice_ids.append(notice_id_int)
                except Notice.DoesNotExist:
                    nonexistent_notice_ids.append(notice_id_int)
            except ValueError:
                # 忽略无效ID
                nonexistent_notice_ids.append(nid)
        
        # 如果有没有权限删除的通知，返回错误
        if unauthorized_notice_ids:
            return Response({
                "code": "A0401",
                "msg": f"无权限删除以下通知公告：{', '.join(map(str, unauthorized_notice_ids))}"
            }, status=403)
        
        # 如果所有通知不存在或已删除，返回错误
        if not authorized_notices:
            return Response({
                "code": "A0404",
                "msg": "所有指定的通知公告不存在或已被删除"
            }, status=404)
        
        # 执行删除操作
        now = timezone.now()
        authorized_notice_ids = [notice.id for notice in authorized_notices]
        
        # 逻辑删除通知公告
        Notice.objects.filter(id__in=authorized_notice_ids).update(
            is_deleted=1,
            update_by=user_id,
            update_time=now
        )
        
        # 物理删除用户通知记录
        UserNotice.objects.filter(notice_id__in=authorized_notice_ids).delete()
        
        # 返回成功响应
        return Response({
            "code": "00000",
            "data": {},
            "msg": f"成功删除{len(authorized_notices)}个通知公告"
        })


class NoticePublishView(APIView):
    """通知公告发布视图"""
    authentication_classes = [JWTAuthentication]
    permission_classes = [IsAuthenticated]
    
    @permission_required(["sys:notice:publish"])
    def put(self, request, notice_id, *args, **kwargs):
        """
        发布通知公告
        
        路径参数:
        - id: 通知公告ID
        """
        # 获取通知公告
        try:
            notice = Notice.objects.get(id=notice_id, is_deleted=0)
        except Notice.DoesNotExist:
            return Response({
                "code": "A0404",
                "msg": "通知公告不存在或已被删除"
            }, status=404)
        
        # 检查数据权限
        token = request.headers.get("Authorization")
        user_id = None
        if token and token.startswith("Bearer "):
            token_str = token[7:]  # 去掉"Bearer "前缀
            
            # 检查用户对该通知的修改权限
            data_permission = data_permission_required(token_str, "update", notice.create_by)
            if data_permission is False:
                return Response({
                    "code": "A0401",
                    "msg": "无权限发布此通知公告"
                }, status=403)
            
            # 获取用户ID
            try:
                decoded_token = jwt.decode(token_str, settings.SIMPLE_JWT.get('SIGNING_KEY', settings.SECRET_KEY), algorithms=["HS256"])
                user_id = decoded_token.get('user_id')
            except jwt.InvalidTokenError:
                pass
        
        # 检查通知公告状态
        if notice.publish_status == 1:
            return Response({
                "code": "A0400",
                "msg": "该通知公告已发布"
            }, status=400)
        
        # 更新通知公告状态
        now = timezone.now()
        notice.publish_status = 1  # 已发布
        notice.publish_time = now
        notice.publisher = user_id
        notice.save(update_fields=['publish_status', 'publish_time', 'publisher'])
        
        # 创建用户通知关系记录
        self._create_user_notices(notice, user_id, token)
        
        # 返回成功响应
        return Response({
            "code": "00000",
            "data": {},
            "msg": "通知公告发布成功"
        })
    
    def _create_user_notices(self, notice, publisher_id, token):
        """为目标用户创建用户通知记录"""
        target_type = notice.target_type
        now = timezone.now()
        
        # 确保发布人自己也收到通知
        publisher_notice_added = False
        
        if target_type == 1:  # 全体用户
            # 获取数据权限
            data_permission = []
            
            if token and token.startswith("Bearer "):
                token_str = token[7:]  # 去掉"Bearer "前缀
                
                try:
                    # 获取当前用户的数据权限范围内的用户
                    data_permission = data_permission_required(token_str, "select")
                except Exception:
                    pass
            
            # 查询所有启用的未删除用户
            query = User.objects.filter(is_deleted=0, status=1)
            
            # 添加数据权限过滤
            if isinstance(data_permission, list) and data_permission:
                query = query.filter(id__in=data_permission)
            
            # 批量创建用户通知记录
            user_notices = []
            for user in query:
                user_notices.append(UserNotice(
                    notice=notice,
                    user=user,
                    is_read=0,
                    create_time=now,
                    is_deleted=0
                ))
                # 检查是否已包含发布人
                if publisher_id and user.id == publisher_id:
                    publisher_notice_added = True
            
            # 批量保存
            if user_notices:
                UserNotice.objects.bulk_create(user_notices)
                
        elif target_type == 2:  # 指定用户
            if notice.target_user_ids:
                # 获取目标用户ID列表
                target_user_ids = notice.target_user_ids.split(',')
                
                # 存储有权限操作的用户ID
                authorized_user_ids = []
                
                if token and token.startswith("Bearer "):
                    token_str = token[7:]  # 去掉"Bearer "前缀
                    
                    # 检查对每个用户的操作权限
                    for user_id in target_user_ids:
                        try:
                            user_id_int = int(user_id.strip())
                            has_permission = data_permission_required(token_str, "add", user_id_int)
                            if has_permission:
                                authorized_user_ids.append(user_id_int)
                                # 检查是否已包含发布人
                                if publisher_id and user_id_int == publisher_id:
                                    publisher_notice_added = True
                        except (ValueError, AttributeError):
                            continue
                
                # 批量创建有权限的用户通知记录
                if authorized_user_ids:
                    users = User.objects.filter(id__in=authorized_user_ids, is_deleted=0, status=1)
                    user_notices = []
                    for user in users:
                        user_notices.append(UserNotice(
                            notice=notice,
                            user=user,
                            is_read=0,
                            create_time=now,
                            is_deleted=0
                        ))
                        # 检查是否已包含发布人
                        if publisher_id and user.id == publisher_id:
                            publisher_notice_added = True
                    
                    # 批量保存
                    if user_notices:
                        UserNotice.objects.bulk_create(user_notices)
        
        # 确保发布人也收到通知（如果还没添加）
        if publisher_id and not publisher_notice_added:
            try:
                publisher = User.objects.get(id=publisher_id, is_deleted=0, status=1)
                UserNotice.objects.create(
                    notice=notice,
                    user=publisher,
                    is_read=0,
                    create_time=now,
                    is_deleted=0
                )
            except User.DoesNotExist:
                pass


class NoticeRevokeView(APIView):
    """通知公告撤回视图"""
    authentication_classes = [JWTAuthentication]
    permission_classes = [IsAuthenticated]
    
    @permission_required(["sys:notice:revoke"])
    def put(self, request, notice_id, *args, **kwargs):
        """
        撤回通知公告
        
        路径参数:
        - id: 通知公告ID
        """
        # 获取通知公告
        try:
            notice = Notice.objects.get(id=notice_id, is_deleted=0)
        except Notice.DoesNotExist:
            return Response({
                "code": "A0404",
                "msg": "通知公告不存在或已被删除"
            }, status=404)
        
        # 检查数据权限
        token = request.headers.get("Authorization")
        user_id = None
        if token and token.startswith("Bearer "):
            token_str = token[7:]  # 去掉"Bearer "前缀
            
            # 检查用户对该通知的修改权限
            data_permission = data_permission_required(token_str, "update", notice.create_by)
            if data_permission is False:
                return Response({
                    "code": "A0401",
                    "msg": "无权限撤回此通知公告"
                }, status=403)
            
            # 获取用户ID
            try:
                decoded_token = jwt.decode(token_str, settings.SIMPLE_JWT.get('SIGNING_KEY', settings.SECRET_KEY), algorithms=["HS256"])
                user_id = decoded_token.get('user_id')
            except jwt.InvalidTokenError:
                pass
        
        # 检查通知公告状态
        if notice.publish_status != 1:
            return Response({
                "code": "A0400",
                "msg": "只有已发布的通知公告才能撤回"
            }, status=400)
        
        # 更新通知公告状态
        now = timezone.now()
        notice.publish_status = -1  # 已撤回
        notice.revoke_time = now
        notice.update_by = user_id
        notice.update_time = now
        notice.save(update_fields=['publish_status', 'revoke_time', 'update_by', 'update_time'])
        
        # 直接删除相关的用户通知记录（物理删除）
        UserNotice.objects.filter(notice=notice).delete()
        
        # 返回成功响应
        return Response({
            "code": "00000",
            "data": {},
            "msg": "通知公告撤回成功"
        })


class NoticeDetailView(APIView):
    """通知公告详情视图"""
    authentication_classes = [JWTAuthentication]
    permission_classes = [IsAuthenticated]
    
    def get(self, request, notice_id, *args, **kwargs):
        """
        获取通知公告详情
        
        路径参数:
        - id: 通知公告ID
        """
        # 获取token和用户ID
        token = request.headers.get("Authorization")
        user_id = None
        if token and token.startswith("Bearer "):
            token_str = token[7:]  # 去掉"Bearer "前缀
            try:
                decoded_token = jwt.decode(token_str, settings.SIMPLE_JWT.get('SIGNING_KEY', settings.SECRET_KEY), algorithms=["HS256"])
                user_id = decoded_token.get('user_id')
            except jwt.InvalidTokenError:
                return Response({
                    "code": "A0401",
                    "msg": "无效的访问令牌"
                }, status=401)
        
        # 获取通知公告
        try:
            notice = Notice.objects.get(id=notice_id, is_deleted=0)
        except Notice.DoesNotExist:
            return Response({
                "code": "A0404",
                "msg": "通知公告不存在或已被删除"
            }, status=404)
        
        # 检查是否有用户通知关系
        if user_id:
            try:
                user_notice = UserNotice.objects.get(
                    notice=notice,
                    user_id=user_id,
                    is_deleted=0
                )
                # 存在用户通知关系，更新为已读状态
                if user_notice.is_read == 0:
                    now = timezone.now()
                    user_notice.is_read = 1
                    user_notice.read_time = now
                    user_notice.update_time = now
                    user_notice.save(update_fields=['is_read', 'read_time', 'update_time'])
                
                # 直接返回通知详情
                serializer = NoticeDetailSerializer(notice)
                return Response({
                    "code": "00000",
                    "data": serializer.data,
                    "msg": "一切ok"
                })
            except UserNotice.DoesNotExist:
                # 不存在用户通知关系，检查数据权限
                if token.startswith("Bearer "):
                    token_str = token[7:]  # 去掉"Bearer "前缀
                    data_permission = data_permission_required(token_str, "select")
                    
                    # 检查数据权限是否包含该通知的创建者
                    if isinstance(data_permission, list) and notice.create_by in data_permission:
                        # 有权限查看，返回通知详情
                        serializer = NoticeDetailSerializer(notice)
                        return Response({
                            "code": "00000",
                            "data": serializer.data,
                            "msg": "一切ok"
                        })
                
                # 无权限查看
                return Response({
                    "code": "A0401",
                    "msg": "无权限查看此通知公告"
                }, status=403)
        
        # 未提供用户ID，无法确认权限
        return Response({
            "code": "A0401",
            "msg": "未提供用户身份信息或无权限"
        }, status=401)


class NoticeFormView(APIView):
    """通知公告表单视图"""
    authentication_classes = [JWTAuthentication]
    permission_classes = [IsAuthenticated]
    
    @permission_required(["sys:notice:query"])
    def get(self, request, notice_id, *args, **kwargs):
        """
        获取通知公告表单数据
        
        路径参数:
        - id: 通知公告ID
        """
        # 获取token
        token = request.headers.get("Authorization")
        if not token or not token.startswith("Bearer "):
            return Response({
                "code": "A0401",
                "msg": "未提供有效的访问令牌"
            }, status=401)
        
        token_str = token[7:]  # 去掉"Bearer "前缀
        
        # 检查数据权限
        data_permission = data_permission_required(token_str, "select")
        if not isinstance(data_permission, list):
            return Response({
                "code": "A0401",
                "msg": "无访问权限"
            }, status=403)
        
        # 获取通知公告
        try:
            notice = Notice.objects.get(id=notice_id, is_deleted=0)
        except Notice.DoesNotExist:
            return Response({
                "code": "A0404",
                "msg": "通知公告不存在或已被删除"
            }, status=404)
        
        # 检查数据权限是否包含该通知的创建者
        if notice.create_by not in data_permission:
            return Response({
                "code": "A0401",
                "msg": "无权限查看此通知公告"
            }, status=403)
        
        # 序列化数据
        serializer = NoticeFormSerializer(notice)
        
        # 返回成功响应
        return Response({
            "code": "00000",
            "data": serializer.data,
            "msg": "一切ok"
        })


class NoticeMyPageView(APIView):
    """用户通知公告分页列表视图"""
    authentication_classes = [JWTAuthentication]
    permission_classes = [IsAuthenticated]
    
    def get(self, request, *args, **kwargs):
        """
        获取当前用户的通知公告分页列表
        
        查询参数:
        - title: 通知标题（可选）
        - publishStatus: 发布状态(1-已发布)（可选）
        - publishTime: 发布时间(起止)（可选）
        - userId: 查询人ID（可选）
        - isRead: 是否已读（0-未读 1-已读）（可选）
        - pageNum: 页码（必需）
        - pageSize: 每页记录数（必需）
        """
        # 获取查询参数
        title = request.query_params.get('title', '')
        publish_status = request.query_params.get('publishStatus', '')
        publish_time = request.query_params.get('publishTime', '')
        is_read = request.query_params.get('isRead', '')
        page_num = request.query_params.get('pageNum', '1')
        page_size = request.query_params.get('pageSize', '10')
        
        # 转换页码和每页记录数为整数
        try:
            page_num = int(page_num)
            page_size = int(page_size)
            # 边界检查
            if page_num < 1:
                page_num = 1
            if page_size < 1:
                page_size = 10
        except ValueError:
            return Response({
                "code": "A0400",
                "msg": "页码或每页记录数格式不正确"
            }, status=400)
        
        # 获取当前用户ID
        token = request.headers.get("Authorization")
        user_id = None
        
        if token and token.startswith("Bearer "):
            token_str = token[7:]  # 去掉"Bearer "前缀
            try:
                decoded_token = jwt.decode(token_str, settings.SIMPLE_JWT.get('SIGNING_KEY', settings.SECRET_KEY), algorithms=["HS256"])
                user_id = decoded_token.get('user_id')
            except jwt.InvalidTokenError:
                return Response({
                    "code": "A0401",
                    "msg": "无效的访问令牌"
                }, status=401)
        
        if not user_id:
            return Response({
                "code": "A0401",
                "msg": "用户未认证"
            }, status=401)
        
        # 查询用户关联的通知 (只查询有效且发布状态为已发布的通知)
        query = Q(user_id=user_id, is_deleted=0, notice__is_deleted=0, notice__publish_status=1)
        
        # 添加标题过滤
        if title:
            query &= Q(notice__title__icontains=title)
        
        # 添加已读状态过滤
        if is_read != '':
            try:
                is_read_int = int(is_read)
                query &= Q(is_read=is_read_int)
            except ValueError:
                pass
        
        # 添加发布时间过滤
        if publish_time:
            time_parts = publish_time.split(',')
            if len(time_parts) == 2:
                start_time, end_time = time_parts
                if start_time:
                    try:
                        start_date = timezone.datetime.strptime(start_time, '%Y-%m-%d %H:%M:%S')
                        query &= Q(notice__publish_time__gte=start_date)
                    except ValueError:
                        pass
                if end_time:
                    try:
                        end_date = timezone.datetime.strptime(end_time, '%Y-%m-%d %H:%M:%S')
                        query &= Q(notice__publish_time__lte=end_date)
                    except ValueError:
                        pass
        
        # 查询记录并按发布时间倒序排序
        user_notices = UserNotice.objects.filter(query).select_related('notice').order_by('-notice__publish_time')
        
        # 获取总记录数
        total = user_notices.count()
        
        # 分页处理
        offset = (page_num - 1) * page_size
        paginated_notices = user_notices[offset:offset+page_size]
        
        # 序列化数据
        serializer = NoticeMyPageSerializer(paginated_notices, many=True)
        
        # 返回结果
        return Response({
            "code": "00000",
            "data": {
                "list": serializer.data,
                "total": total
            },
            "msg": "一切ok"
        })


class NoticeReadAllView(APIView):
    """通知公告全部已读视图"""
    authentication_classes = [JWTAuthentication]
    permission_classes = [IsAuthenticated]
    
    def put(self, request, *args, **kwargs):
        """
        将当前用户的所有未读通知标记为已读
        """
        # 获取当前用户ID
        token = request.headers.get("Authorization")
        user_id = None
        
        if token and token.startswith("Bearer "):
            token_str = token[7:]  # 去掉"Bearer "前缀
            try:
                decoded_token = jwt.decode(token_str, settings.SIMPLE_JWT.get('SIGNING_KEY', settings.SECRET_KEY), algorithms=["HS256"])
                user_id = decoded_token.get('user_id')
            except jwt.InvalidTokenError:
                return Response({
                    "code": "A0401",
                    "msg": "无效的访问令牌"
                }, status=401)
        
        if not user_id:
            return Response({
                "code": "A0401",
                "msg": "用户未认证"
            }, status=401)
        
        # 查询当前用户的所有未读通知
        now = timezone.now()
        unread_count = UserNotice.objects.filter(
            user_id=user_id,
            is_read=0,
            is_deleted=0,
            notice__is_deleted=0,
            notice__publish_status=1
        ).update(
            is_read=1,
            read_time=now,
            update_time=now
        )
        
        # 返回成功响应
        return Response({
            "code": "00000",
            "data": {
                "count": unread_count
            },
            "msg": f"已将{unread_count}条通知标记为已读"
        })
